package com.iflysse.services.impl;

import com.iflysse.common.ResultEnum;
import com.iflysse.dao.*;
import com.iflysse.pojo.bo.CommonBoResp;
import com.iflysse.pojo.bo.req.*;
import com.iflysse.pojo.bo.resp.*;
import com.iflysse.pojo.po.common.CommonPoResp;
import com.iflysse.pojo.po.req.*;
import com.iflysse.pojo.po.resp.*;
import com.iflysse.services.ResourceService;
import com.iflysse.util.CommonUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Service
public class ResourceServiceImpl implements ResourceService {
    public static final Logger log = Logger.getLogger(ActivityServiceImpl.class);
    @Autowired
    ResourceDao resourceDao;
    @Autowired
    KnowledgePointDao knowledgePointDao;
    @Autowired
    QuestionDao questionDao;
    @Autowired
    ResourceHtmlDao resourceHtmlDao;
    @Autowired
    ResourceDocDao resourceDocDao ;
    @Autowired
    ResourceVideoDao resourceVideoDao;
    @Autowired
    ResourceTestDao resourceTestDao;
    @Autowired
    TaskDao taskDao;
    @Autowired
    ChapterDao chapterDao;
    @Autowired
    CourseDao   courseDao;
    @Autowired
    StudentSearchRecordDao studentSearchRecordDao;
    /**
     * 添加资源
     * 注:添加试题资源页时,多个问题需要多次调用
     * @param addResourceBoReq  ,抽象类,
     *                          具体子类有:AddResourceHtmlBoReq,
     *                          AddResourceDocBoReq,
     *                          AddResourceVideoBoReq,
     *                          AddResourceQuestionBoReq
     * @return
     */
    @Transactional
    public CommonBoResp addResource(AddResourceBoReq addResourceBoReq) throws SQLException {

        CommonBoResp commonBoResp = new CommonBoResp();
        CommonPoResp commonPoResp= new CommonPoResp();
        String resourceId = "";
        int type = 0;//类型
        String typeName="";//类型名称
            if (addResourceBoReq instanceof AddResourceHtmlBoReq) {

                AddResourceHtmlBoReq addResourceHtmlBoReq = (AddResourceHtmlBoReq) addResourceBoReq;
                //将业务层对象转成数据层请求对象
                AddResourceHtmlPoReq addResourceHtmlPoReq = CommonUtil.objToObj(addResourceBoReq, AddResourceHtmlPoReq.class);

                int i = resourceHtmlDao.addResourceHtml(addResourceHtmlPoReq);
                CommonUtil.printToPoResult(commonPoResp,i);
                resourceId = addResourceHtmlPoReq.getResourceId();
                type = 1;
                typeName = "页面";
            } else if (addResourceBoReq instanceof AddResourceDocBoReq) {

                AddResourceDocBoReq addResourceDocBoReq = (AddResourceDocBoReq) addResourceBoReq;
                AddResourceDocPoReq addResourceDocPoReq = CommonUtil.objToObj(addResourceDocBoReq, AddResourceDocPoReq.class);
                int update = resourceDocDao.addResourceDoc(addResourceDocPoReq);
                CommonUtil.printToPoResult(commonPoResp,update);
                resourceId = addResourceDocPoReq.getResourceId();
                type = 2;
                typeName = "文档_" + addResourceDocPoReq.getDocType();

            } else if (addResourceBoReq instanceof AddResourceVideoBoReq) {

                AddResourceVideoBoReq addResourceVideoBoReq = (AddResourceVideoBoReq) addResourceBoReq;
                AddResourceVideoPoReq addResourceVideoPoReq = CommonUtil.objToObj(addResourceVideoBoReq, AddResourceVideoPoReq.class);
                int flage = resourceVideoDao.addResourceVideo(addResourceVideoPoReq);
                CommonUtil.printToPoResult(commonPoResp,flage);
                resourceId = addResourceVideoPoReq.getResourceId();
                type = 3;
                typeName = "视频";
            } else if (addResourceBoReq instanceof AddResourceTestBoReq) {
                //一个问题对应一个课程页,所以前端选多题是,业务层需要调用多次

                AddResourceTestBoReq addResourceTestBoReq = (AddResourceTestBoReq) addResourceBoReq;
                AddTestQuestToResourcePoReq addResourceTestPoReq = CommonUtil.objToObj(addResourceTestBoReq, AddTestQuestToResourcePoReq.class);
                int s = resourceTestDao.addTestQuestionToResource(addResourceTestPoReq);
                CommonUtil.printToPoResult(commonPoResp,s);
                resourceId=addResourceTestPoReq.getResourceId();
                type = 4;
                typeName = "练习";
            }
            //将资源和章绑定
            AddResourceToChapterPoReq addResourceToChapterPoReq = new AddResourceToChapterPoReq();
            addResourceToChapterPoReq.setResourceId(resourceId);
            addResourceToChapterPoReq.setChapterId(addResourceBoReq.getChapterId());
            addResourceToChapterPoReq.setResourceType(type);
            addResourceToChapterPoReq.setResourceTypeName(typeName);
            addResourceToChapterPoReq.setResourceTitle(addResourceBoReq.getResourceTitle());
            resourceDao.addResourceToChapter(addResourceToChapterPoReq);


            //资源和知识点绑定
            if (addResourceBoReq.getKnowledgePointIdList() != null && addResourceBoReq.getKnowledgePointIdList().size() > 0) {
                ResourceKnowledgePointPoReq resourceKnowledgePointPoReq = new ResourceKnowledgePointPoReq();
                resourceKnowledgePointPoReq.setResourceId(resourceId);
                resourceKnowledgePointPoReq.setKnowledgePointIdList(addResourceBoReq.getKnowledgePointIdList());
                knowledgePointDao.addKnowledgePointToResource(resourceKnowledgePointPoReq);
            }

            //数据转换
            commonBoResp = CommonUtil.objToObj(commonPoResp, CommonBoResp.class);


        return commonBoResp;
    }

    /**
     * 根据章编号获取资源
     *
     * @param chapterIdBoReq 章编号
     * @return
     */
    @Override
    public ResourceListBoResp loadResourceByChapterId(ChapterIdBoReq chapterIdBoReq) throws SQLException {
        ChapterIdPoReq chapterIdPoReq = CommonUtil.objToObj(chapterIdBoReq, ChapterIdPoReq.class);
        //resourceDao.
        ResourceListPoResp resourceListPoResp = new ResourceListPoResp();
        List<ResourcePoResp> resourceBoRespList1= resourceDao.getResourceByChapterId(chapterIdPoReq);
        resourceListPoResp.setResourceBoRespList(resourceBoRespList1);
        ResourceListBoResp resourceListBoResp = new ResourceListBoResp();
        resourceListBoResp.setResourceBoRespList(new ArrayList<>());
        resourceListPoResp.getResourceBoRespList().forEach(resourcePoResp -> {
            ResourceBoResp resourceBoResp = CommonUtil.objToObj(resourcePoResp, ResourceBoResp.class);
            resourceListBoResp.getResourceBoRespList().add(resourceBoResp);

        });
        return resourceListBoResp;
    }

    /**
     * 根据资源编号获取html资源
     *
     * @param resourceIdBoReq
     * @return
     */
    @Override
    public ResourceHtmlBoResp getHtmlResourceByResourceId(ResourceIdBoReq resourceIdBoReq) throws SQLException {
        ResourceIdPoReq resourceIdPoReq = CommonUtil.objToObj(resourceIdBoReq, ResourceIdPoReq.class);
        resourceIdPoReq.setResouceId(resourceIdBoReq.getResourceId());
        ResourceHtmlPoResp htmlResource = resourceDao.getHtmlResourceByResourceId(resourceIdPoReq);
        ResourceHtmlBoResp resourceHtmlBoResp = CommonUtil.objToObj(htmlResource, ResourceHtmlBoResp.class);
        //父类属性无法通过工具类映射
        resourceHtmlBoResp.setResourceId(htmlResource.getResourceId());
        resourceHtmlBoResp.setLearningTime(htmlResource.getLearningTime());
        resourceHtmlBoResp.setResourceTitle(htmlResource.getResourceTitle());
        resourceHtmlBoResp.setResourceType(htmlResource.getResourceType());
        return resourceHtmlBoResp;
    }

    /**
     * 根据资源编号获取文档和视频资源
     *
     * @param resourceIdBoReq
     * @return
     */
    @Override
    public ResourceDocAndVideoBoResp getDocAndVideoResourceByResourceId(ResourceIdBoReq resourceIdBoReq) throws SQLException {
        ResourceIdPoReq resourceIdPoReq = CommonUtil.objToObj(resourceIdBoReq, ResourceIdPoReq.class);
        resourceIdPoReq.setResouceId(resourceIdBoReq.getResourceId());
        ResourceDocAndVideoPoResp docAndVideoResourcePoResp = resourceDao.getDocAndVideoResourceByResourceId(resourceIdPoReq);
        ResourceDocAndVideoBoResp resourceDocAndVideoBoResp = CommonUtil.objToObj(docAndVideoResourcePoResp, ResourceDocAndVideoBoResp.class);

        resourceDocAndVideoBoResp.setResPath(docAndVideoResourcePoResp.getResourcePath());
        //父类属性无法通过工具类映射
        resourceDocAndVideoBoResp.setResourceId(docAndVideoResourcePoResp.getResourceId());
        resourceDocAndVideoBoResp.setLearningTime(docAndVideoResourcePoResp.getLearningTime());
        resourceDocAndVideoBoResp.setResourceTitle(docAndVideoResourcePoResp.getResourceTitle());
        resourceDocAndVideoBoResp.setResourceType(docAndVideoResourcePoResp.getResourceType());
        return resourceDocAndVideoBoResp;
    }

    /**
     * 根据资源编号获取测试资源
     *
     * @param resourceIdBoReq
     * @return
     */
    @Override
    public ResourceTestBoResp getTestResourceByResourceId(ResourceIdBoReq resourceIdBoReq) throws SQLException {
        ResourceIdPoReq resourceIdPoReq = CommonUtil.objToObj(resourceIdBoReq, ResourceIdPoReq.class);
        resourceIdPoReq.setResouceId(resourceIdBoReq.getResourceId());
        //获取资源相关信息,并且得到测试资源中问题的编号
        ResourceTestPoResp testResource =new ResourceTestPoResp();
        QuestionPoResp q= resourceDao.getTestResourceByResourceId(resourceIdPoReq);
        testResource.setQuestionPoResp(q);
        //根据问题编号获取问题详情
        QuestionPoResp questionPoResp = questionDao.getQuestionByQuestionId(testResource.getQuestionPoResp().getQuestionId());

        QuestionBoResp questionBoResp = CommonUtil.objToObj(questionPoResp, QuestionBoResp.class);
        ResourceTestBoResp resourceTestBoResp = CommonUtil.objToObj(testResource, ResourceTestBoResp.class);
        //父类属性无法通过工具类映射
        resourceTestBoResp.setResourceId(testResource.getResourceId());
        resourceTestBoResp.setResourceId(testResource.getResourceId());
        resourceTestBoResp.setLearningTime(testResource.getLearningTime());
        resourceTestBoResp.setResourceTitle(testResource.getResourceTitle());
        resourceTestBoResp.setResourceType(testResource.getResourceType());
        resourceTestBoResp.setQuestionBoResp(questionBoResp);
        return resourceTestBoResp;
    }


    @Override
    public StudentLearnResourceListBoResp loadStudentLearnResourceByChapterId(StudentChapterIdBoReq chapterIdBoReq) throws SQLException {
        ChapterIdPoReq chapterIdPoReq = CommonUtil.objToObj(chapterIdBoReq,ChapterIdPoReq.class);
        ResourceListPoResp resourceListBoResp = new ResourceListPoResp();
        //resourceDao.根据章节获取资源列表
        List<ResourcePoResp> resourceByChapterId = resourceDao.getResourceByChapterId(chapterIdPoReq);
        resourceListBoResp.setResourceBoRespList(resourceByChapterId);

        StudentLearnResourceListBoResp studentLearnResourceListBoResp = new StudentLearnResourceListBoResp();


        for(int i = 0;i<resourceListBoResp.getResourceBoRespList().size();i++){
            ResourcePoResp resourcePoResp = resourceListBoResp.getResourceBoRespList().get(i);
            StudentLearnResourceBoResp resourceBoResp = CommonUtil.objToObj(resourcePoResp,StudentLearnResourceBoResp.class);
            int count = resourceDao.getStudentLearnRecordByResourceIdAndStudentId(chapterIdBoReq.getTaskId(),resourcePoResp.getResourceId(), chapterIdBoReq.getStudentId());
            resourceBoResp.setLearningRecord(count);
            studentLearnResourceListBoResp.getStudentLearnResourceBoRespList().add(resourceBoResp);
        }
        return studentLearnResourceListBoResp;
    }

    @Transactional
    @Override
    public CommonBoResp addStudentLearnRecord(StudentLearnRecordBoReq studentLearnRecordBoReq) throws SQLException {
        StudentLearnRecordPoReq studentLearnRecordPoReq = CommonUtil.objToObj(studentLearnRecordBoReq,StudentLearnRecordPoReq.class);
        //判断该资源是否已经学过
        int record = resourceDao.getStudentLearnRecordByResourceIdAndStudentId(studentLearnRecordBoReq.getTaskId(),studentLearnRecordBoReq.getResourceId(),studentLearnRecordPoReq.getStudentId());
        CommonPoResp commonPoResp = new CommonPoResp();
        commonPoResp.setCode(ResultEnum.SUCCESS.getCode());
        commonPoResp.setMsg(ResultEnum.SUCCESS.getMsg());
        if(record ==0) {
            int result = resourceDao.addStudentLearnRecord(studentLearnRecordPoReq);
            CommonUtil.printToPoResult(commonPoResp,result);
            taskDao.updateLearnResourceAmountByTaskIdAndStudentId(studentLearnRecordPoReq.getTaskId(), studentLearnRecordPoReq.getStudentId());
            //判断任务是否已经完成
            //获取任务数量
            int resourceNum = taskDao.getTaskResourceAmountByTaskId(studentLearnRecordBoReq.getTaskId());
            //获取已经学完的资源数量
            StudentIdAndTaskIdPoReq studentIdAndTaskIdPoReq = new StudentIdAndTaskIdPoReq();
            studentIdAndTaskIdPoReq.setStudentId(studentLearnRecordBoReq.getStudentId());
            studentIdAndTaskIdPoReq.setTaskId(studentLearnRecordBoReq.getTaskId());
            int learnedNum = taskDao.getLearnedResourceNumberByStudentIdAndTaskId(studentIdAndTaskIdPoReq);
            if(learnedNum>=resourceNum){
                //学习完成
                //更新本任务的状态,
                taskDao.updateStudentTaskStateByTaskIdAndStudentId(
                        studentLearnRecordPoReq.getTaskId(),
                        studentLearnRecordPoReq.getStudentId(),1
                );

                //任务的学习完成人数需要更新
                taskDao.updateTaskCompleteNumberByTaskId(studentLearnRecordBoReq.getTaskId());
            }



        }return CommonUtil.objToObj(commonPoResp,CommonBoResp.class);
    }

    @Override
    public SearchResourceListBoResp getResourceByKeywords(String keywords, String studentId) throws SQLException {
        //查询章资源表
        List<SearchResourcePoResp> searchResourceByKeywords = resourceDao.getSearchResourceByKeywords(keywords);
        SearchResourceListBoResp searchResourceListBoResp = getSearchResourceListBoResp(searchResourceByKeywords);
        //添加查询记录
        studentSearchRecordDao.addStudentSearchRecord(keywords,studentId);

        return searchResourceListBoResp;
    }


    /**
     * 根据资源获取资源的封面信息,并返回service层对象
     * @param searchResourceByKeywords
     * @return
     * @throws SQLException
     */
    private SearchResourceListBoResp getSearchResourceListBoResp(List<SearchResourcePoResp> searchResourceByKeywords) throws SQLException {
        SearchResourceListBoResp searchResourceListBoResp = new SearchResourceListBoResp();
        for(int i = 0; i< searchResourceByKeywords.size(); i++){
            SearchResourceBoResp searchResourceBoResp = CommonUtil.objToObj(searchResourceByKeywords.get(i),SearchResourceBoResp.class);
            searchResourceListBoResp.getSearchResourceBoRespList()
                    .add(searchResourceBoResp);
            //查询资源所属课程信息
            String chapterId = chapterDao.getChapterIdByResourceId(searchResourceBoResp.getResourceId());
            ChapterIdPoReq chapterIdPoReq = new ChapterIdPoReq();
            chapterIdPoReq.setChapterId(chapterId);
            String courseId = chapterDao.getCourseIdByChapterId(chapterIdPoReq);
            CourseIdPoReq courseIdPoReq = new CourseIdPoReq();
            courseIdPoReq.setCourseId(courseId);
            String courseCover = courseDao.getCourseCoverByCourseId(courseIdPoReq);
            searchResourceBoResp.setCourseCover(courseCover);

        }
        return searchResourceListBoResp;
    }

    @Override
    public SearchResourceListBoResp getResourceByResourceIds(List<String> resourceIds) throws SQLException {
        List<SearchResourcePoResp> searchResourceByKeywords = resourceDao.getSearchResourceByResourceIds(resourceIds);

        SearchResourceListBoResp searchResourceListBoResp = getSearchResourceListBoResp(searchResourceByKeywords);

        return searchResourceListBoResp;

    }


}
